﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YJKGeometryFuncs;
using YJKRevitDimensionText.Utility;

namespace YJKRevitDimension.ArrowDimension
{
	internal class ArrowDimText
	{
		public static Result FindAndModifyText(UIDocument m_UIdoc, Autodesk.Revit.DB.Document doc, ArrowDimData data, List<XYZ> LstPickPoint, List<DetailCurve> LstDetailCurve, int nUpOrDown)
		{
			double num = (LstPickPoint[LstPickPoint.Count - 1] - LstPickPoint[LstPickPoint.Count - 2]).AngleOnPlaneTo(m_UIdoc.ActiveView.RightDirection, -m_UIdoc.ActiveView.ViewDirection);
			Transaction transaction = new Transaction(doc, "修改文字");
			Result result;
			try
			{
				Element element = null;
				string text = string.Empty;
				string text2 = string.Empty;
				if (nUpOrDown.Equals(1))
				{
					text = "线上文字";
					if (!data.StrAlignStyle.Equals("在线端"))
					{
						if (num <= Math.PI*.5 || num > 4.71238898038469)
						{
							text2 = data.StrLineUpText;
							ArrowDimText.m_bRotate = true;
						}
						else
						{
							text2 = data.StrLineDownText;
						}
					}
					else
					{
						text2 = data.StrLineUpText;
					}
				}
				else if (nUpOrDown.Equals(-1))
				{
					text = "线下文字";
					if (!data.StrAlignStyle.Equals("在线端"))
					{
						if (num <= Math.PI*.5 || num > 4.71238898038469)
						{
							text2 = data.StrLineDownText;
							ArrowDimText.m_bRotate = true;
						}
						else
						{
							text2 = data.StrLineUpText;
						}
					}
				}
				FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
				filteredElementCollector.OfCategory(BuiltInCategory.OST_GenericAnnotation);
				foreach (Element element2 in filteredElementCollector.WhereElementIsNotElementType())
				{
					if (element2.Name == text)
					{
						element = element2;
						break;
					}
				}
				ArrowDimText.GetLoadedSymbols(doc, element as FamilyInstance, data);
				double txtLength = 1.0;
				transaction.Start();
				ArrowDimText.ChangeTextNote(doc, text, text2);
				if (data.StrAlignStyle.Equals("在线端"))
				{
					txtLength = 0.0;
				}
				else if (m_UIdoc.Application.Application.VersionNumber == "2015")
				{
					double num2 = AssistFunc.mmToFeet(Convert.ToDouble(data.StrTextHeight));
					txtLength = (double)(text2.Length + 1) * Convert.ToDouble(data.StrTextWidth) * num2;
				}
				else
				{
					ArrowDimText.GetAnnotationSymbolLength(m_UIdoc.Document, text2, data, ref txtLength);
				}
				XYZ xyz = ArrowDimText.ComputeTextLocation(m_UIdoc, LstPickPoint, LstDetailCurve, nUpOrDown, data, txtLength);
				LocationPoint locationPoint = element.Location as LocationPoint;
				ElementTransformUtils.MoveElement(doc, element.Id, xyz - locationPoint.Point);
				locationPoint = (element.Location as LocationPoint);
				if (!data.StrAlignStyle.Equals("在线端"))
				{
					ElementTransformUtils.RotateElement(doc, element.Id, Line.CreateBound(locationPoint.Point, locationPoint.Point.Add(XYZ.BasisZ)), num);
					if (!ArrowDimText.m_bRotate)
					{
						ElementTransformUtils.RotateElement(doc, element.Id, Line.CreateBound(locationPoint.Point, locationPoint.Point.Add(XYZ.BasisZ)), Math.PI);
					}
				}
				ArrowDimText.TxtEnable(doc, data);
				transaction.Commit();
				ArrowDimText.m_bRotate = false;
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception)
			{
				transaction.RollBack();
				result = Autodesk.Revit.UI.Result.Failed;
			}
			return result;
		}

		private static void ChangeTextNote(Autodesk.Revit.DB.Document doc, string strName, string strNote)
		{
			FamilyManager familyManager = doc.FamilyManager;
			IList<FamilyParameter> parameters = familyManager.GetParameters();
			for (int i = 0; i < parameters.Count; i++)
			{
				if (parameters[i].Definition.Name.Equals(strName))
				{
					familyManager.Set(parameters[i], strNote);
					return;
				}
			}
		}

		private static void GetAnnotationSymbolLength(Autodesk.Revit.DB.Document doc, string strNote, ArrowDimData data, ref double dRealLength)
		{
			TextNoteType textNoteType = null;
			ElementClassFilter elementClassFilter = new ElementClassFilter(typeof(TextNoteType));
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.WherePasses(elementClassFilter).WhereElementIsElementType();
			Transaction transaction = new Transaction(doc, "临时文字长度获取");
			try
			{
				double num = AssistFunc.mmToFeet(Convert.ToDouble(data.StrTextHeight));
				transaction.Start();
				foreach (Element element in filteredElementCollector)
				{
					if (element is TextNoteType)
					{
						textNoteType = ((element as TextNoteType).Duplicate("箭头标注测试文字样式") as TextNoteType);
						textNoteType.get_Parameter(BuiltInParameter.TEXT_FONT).Set(data.StrFontType);
						textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).Set(num);
						textNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).Set(Convert.ToDouble(data.StrTextWidth));
						textNoteType.get_Parameter(BuiltInParameter.TEXT_STYLE_ITALIC).Set(0);
						textNoteType.get_Parameter(BuiltInParameter.TEXT_STYLE_BOLD).Set(0);
						break;
					}
				}
				if (textNoteType != null)
				{
					int length = strNote.Length;
					Convert.ToDouble(data.StrTextWidth);
					TextNote txtNote = TextNote.Create(doc, doc.ActiveView.Id, doc.ActiveView.Origin, strNote, textNoteType.Id);
					doc.Regenerate();
					dRealLength = RevitElementExtension.GetTextNoteWidth(txtNote);
				}
				transaction.RollBack();
			}
			catch (Exception)
			{
				if (transaction.IsValidObject && transaction.HasStarted())
				{
					transaction.RollBack();
				}
			}
		}

		public static void GetLoadedSymbols(Autodesk.Revit.DB.Document document, FamilyInstance familyInstance, ArrowDimData data)
		{
			if (familyInstance.Symbol != null)
			{
				Family family = familyInstance.Symbol.Family;
				Document document2 = document.EditFamily(family);
				if (document2 != null && document2.IsFamilyDocument)
				{
                    //"FamilySymbols in " + family.Name + ":\n";
					Transaction transaction = new Transaction(document2);
					try
					{
						transaction.Start("CreateText");
						foreach (Element element in new FilteredElementCollector(document2).OfClass(typeof(TextElement)).ToElements())
						{
							TextElement textElement = (TextElement)element;
							if (textElement.Text.Contains(familyInstance.Name))
							{
								TextElementType symbol = textElement.Symbol;
								symbol.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).Set(Convert.ToDouble(data.StrTextWidth));
								symbol.get_Parameter(BuiltInParameter.TEXT_SIZE).Set(Convert.ToDouble(data.StrTextHeight) / 304.8);
								symbol.get_Parameter(BuiltInParameter.TEXT_FONT).Set(data.StrFontType);
								textElement.ChangeTypeId(symbol.Id);
							}
						}
						transaction.Commit();
					}
					catch (Exception)
					{
						transaction.RollBack();
					}
					try
					{
						document2.LoadFamily(document, new MyFamilyLoadOptions());
					}
					catch (Exception)
					{
						throw;
					}
				}
			}
		}

		public static XYZ ComputeTextLocation(UIDocument m_UIdoc, List<XYZ> LstPickPoint, List<DetailCurve> LstDetailCurve, int nUpOrDown, ArrowDimData data, double txtLength)
		{
			m_UIdoc.Document.ActiveView.get_Parameter(BuiltInParameter.VIEW_SCALE).AsInteger();
			Transform aviewTransform = ArrowDimTempFamily.GetAViewTransform(m_UIdoc.ActiveView);
			XYZ xyz = (Geometry.TransformPoint(LstPickPoint[LstPickPoint.Count - 1], aviewTransform) - Geometry.TransformPoint(LstPickPoint[LstPickPoint.Count - 2], aviewTransform)).Normalize();
			XYZ xyz2 = new Transform(Transform.Identity)
			{
				BasisX = XYZ.BasisY * (double)nUpOrDown,
				BasisY = -XYZ.BasisX * (double)nUpOrDown
			}.OfVector(xyz) * AssistFunc.mmToFeet(Convert.ToDouble(data.StrDistance) + Convert.ToDouble(data.StrTextHeight) / 2.0);
			Line line = (LstDetailCurve[LstDetailCurve.Count - 1].Location as LocationCurve).Curve as Line;
			XYZ xyz3 = line.Evaluate(0.5, true);
			XYZ xyz4;
			if (data.StrAlignStyle.Equals("齐线端"))
			{
				XYZ endPoint = line.GetEndPoint(1);
				xyz4 = endPoint - (endPoint - xyz3).Normalize() * txtLength / 2.0;
				xyz4 = xyz4.Add(xyz2);
			}
			else if (data.StrAlignStyle.Equals("齐线中"))
			{
				xyz4 = xyz3.Add(xyz2);
			}
			else
			{
				xyz4 = xyz3.Add(line.Direction * (line.Length / 2.0 + txtLength / 2.0 + AssistFunc.mmToFeet(Convert.ToDouble(data.StrDistance))));
			}
			return xyz4;
		}

		private static void TxtEnable(Autodesk.Revit.DB.Document doc, ArrowDimData data)
		{
			FamilyManager familyManager = doc.FamilyManager;
			IList<FamilyParameter> parameters = familyManager.GetParameters();
			for (int i = 0; i < parameters.Count; i++)
			{
				if (data.StrAlignStyle.Equals("在线端") && parameters[i].Definition.Name.Contains("线下文字可见性"))
				{
					familyManager.Set(parameters[i], 0);
				}
				if (!data.StrAlignStyle.Equals("在线端"))
				{
					if (string.IsNullOrWhiteSpace(data.StrLineUpText))
					{
						if (ArrowDimText.m_bRotate && parameters[i].Definition.Name.Contains("线上文字可见性"))
						{
							familyManager.Set(parameters[i], 0);
						}
						else if (!ArrowDimText.m_bRotate && parameters[i].Definition.Name.Contains("线下文字可见性"))
						{
							familyManager.Set(parameters[i], 0);
						}
					}
					if (string.IsNullOrWhiteSpace(data.StrLineDownText))
					{
						if (ArrowDimText.m_bRotate && parameters[i].Definition.Name.Contains("线下文字可见性"))
						{
							familyManager.Set(parameters[i], 0);
						}
						else if (!ArrowDimText.m_bRotate && parameters[i].Definition.Name.Contains("线上文字可见性"))
						{
							familyManager.Set(parameters[i], 0);
						}
					}
				}
			}
		}

		public static double TxtNoteLength(string txtNote, double txtH, double txtWS)
		{
			double num = 2.0;
			double num2 = txtH * txtWS / num / 304.8;
			return (double)SpecialCharactorDrawingKit.GetLength(txtNote) * num2;
		}

		public static bool m_bRotate;
	}
}
